package com.andreamerla.petslife.manager;

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
import com.andreamerla.petslife.PetsLifeApplication;
import com.andreamerla.petslife.util.Utils;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: a.merla
 * Date: 19/07/13
 * Time: 14.05
 */
public class GpsTracker extends Service implements LocationListener {
    private static GpsTracker instance;

    private final Context context;
    private LocationManager locationManager;
    private List<LocationListener> locationListenerList = new ArrayList<LocationListener>();

    private boolean isGPSEnabled = false;
    private boolean isNetworkEnabled = false;
    private Location location = null;

    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 10; // 10 meters
    private static final long MIN_TIME_BW_UPDATES = 1; // 1000 * 60 * 1; // 1 minute

    private GpsTracker() {
        this.context = PetsLifeApplication.getAppContext();
        initGpsTracker();
    }

    public static GpsTracker getInstance() {
        if (instance == null)
            instance = new GpsTracker();

        instance.startGpsTracking();
        return instance;
    }

    private void initGpsTracker() {
        locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);

        // Get GPS status
        isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

        // Get network status
        isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    }

    public Location getLocation() {
        if (locationManager != null)
            location = locationManager.getLastKnownLocation(getProvider());

        return location;
    }

    private String getProvider() {
        if (isGPSEnabled)
            return LocationManager.GPS_PROVIDER;
        if (isNetworkEnabled)
            return LocationManager.NETWORK_PROVIDER;

        Log.e(Utils.getLogTag(this.getClass()), "No provider enabled: can't obtain user position");
        return null;
    }

    public void startGpsTracking() {
        String provider = getProvider();
        if (provider == null)
            return;

        locationManager.requestLocationUpdates(provider, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
        Log.d(Utils.getLogTag(this.getClass()), "Using " + provider + " provider for location updates");
        if (locationManager != null)
            location = locationManager.getLastKnownLocation(provider);
    }

    public void stopGpsTracking() {
        if (locationManager != null)
            locationManager.removeUpdates(this);
    }

    /**
     * Check if GPS or WiFi are enabled
     *
     * @return boolean
     */
    public boolean canGetLocation() {
        return isGPSEnabled || isNetworkEnabled;
    }

    /**
     * Show settings alert dialog.
     * On pressing Settings button will launch Settings Options.
     */
    public void showSettingsAlert() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
        alertDialog.setTitle("GPS disabled");
        alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
        alertDialog.setPositiveButton("Settings",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        context.startActivity(intent);
                    }
                });
        alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });
        alertDialog.show();
    }

    public void addLocationListener(LocationListener locationListener) {
        locationListenerList.add(locationListener);
    }

    public void onLocationChanged(Location location) {
        this.location = location;
        for (LocationListener ll : locationListenerList)
            if (ll != null)
                ll.onLocationChanged(location);
    }

    public void onProviderDisabled(String provider) {
        for (LocationListener ll : locationListenerList)
            if (ll != null)
                ll.onProviderDisabled(provider);
    }

    public void onProviderEnabled(String provider) {
        for (LocationListener ll : locationListenerList)
            if (ll != null)
                ll.onProviderEnabled(provider);
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
        for (LocationListener ll : locationListenerList)
            if (ll != null)
                ll.onStatusChanged(provider, status, extras);
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
}
